package org.hxzon.rpggame.util;

import java.io.File;
import java.io.FileReader;
import java.io.Writer;

import javax.script.Invocable;
import javax.script.ScriptEngine;
import javax.script.ScriptEngineManager;

import org.slf4j.Logger;
import org.slf4j.LoggerFactory;

public class ScriptEngineUtil {

    private static final Logger logger = LoggerFactory.getLogger(ScriptEngineUtil.class);
    private static ScriptEngine engine;
    static {
        ScriptEngineManager engineManager = new ScriptEngineManager();
        engine = engineManager.getEngineByName("nashorn");
    }

    //================
    public static void loadScripts(String base, String[] files) {
        for (String f : files) {
            loadScript(new File(base + f));
        }
    }

    public static void loadScript(File file) {
        if (file.isDirectory()) {
            for (File f : file.listFiles()) {
                loadScript(f);
            }
        } else {
            _loadScript(file);
        }
    }

    //================
    private static void _loadScript(File file) {
        eval(file);
    }

    public static Object invoke(String fn, Object... params) {
        try {
            return ((Invocable) engine).invokeFunction(fn, params);
        } catch (Exception e) {
            logger.error(fn, e);
            return null;
        }
    }

    public static void put(String name, Object value) {
        engine.put(name, value);
    }

    public static Object eval(String str) {
        try {
            return engine.eval(str);
        } catch (Exception e) {
            throw new RuntimeException(e);
        }
    }

    public static Object eval(File file) {
        try {
            return engine.eval(new FileReader(file));
        } catch (Exception e) {
            throw new RuntimeException(file.getAbsolutePath(), e);
        }
    }

    public static Object eval(String str, Writer w) {
        Writer orig = engine.getContext().getWriter();
        try {
            engine.getContext().setWriter(w);
            return engine.eval(str);
        } catch (Exception e) {
            throw new RuntimeException(e);
        } finally {
            engine.getContext().setWriter(orig);
        }
    }

}
